import Snake from "./snake";
import Food from "./food";
import Scorepanel from "./scorepanel";

class Gamecontrol {
  snake:Snake
  food:Food
  scorepanel:Scorepanel
  // 改变方法的key值
  keyArr:string[] = ['ArrowUp','Up','ArrowDown','Down','ArrowLeft','Left','ArrowRight','Right']
  // 定义定时器
  private timer:number | undefined = undefined
  // 定义蛇头运行方向
  direction:string = ''
  // 定义蛇头上一次运动方向
  lastDirec:string = ""
  // 是否暂停
  isPuse:boolean = false
  constructor(){
    this.snake = new Snake()
    this.food = new Food()
    this.scorepanel  = new Scorepanel()
    // 初始化
    this.init()
  }

  // 初始化
  init():void{
    this.eventLisenter()
  }

  // 事件监听
  eventLisenter():void{
    document.addEventListener('keydown',this.keydownHandler.bind(this))
  }

  // 游戏按键处理函数
  keydownHandler(e:KeyboardEvent):void{
    // console.log(e.key);
    // 暂停游戏
    if(e.key === 'Enter') {
      this.puse()
      return
    }

    // 改变方向做限制
    if(this.keyArr.includes(e.key)) {
      this.lastDirec = this.direction
      this.direction = e.key
      this.run()
    }
  }

  run():void{
    if(this.timer) clearInterval(this.timer)
    this.timer = window.setInterval(()=>{
      // 获取初始坐标
      let x = this.snake.Hx
      let y = this.snake.Hy
      // 获取运动后的坐标
      let res = this.step(x,y)
      // 判断蛇是否掉头了
      if(this.isBack(res.x,res.y)){
        // 如果掉头了，让其方向回到上一次运动的方向
        if(this.lastDirec === '') return
        this.direction = this.lastDirec
        // 重新获取运动后的坐标
        res = this.step(x,y)
      }
      // 检查蛇是否吃到食物
      this.checkEat(x,y)
      try {
        // 改变坐标
        this.snake.Hx = res.x
        this.snake.Hy = res.y
      } catch (error) {
        console.log(error);
        this.gameover()
      }
    },300 - (this.scorepanel.level - 1)*30)
  }

  // 蛇头运动方式
  step(x:number,y:number):{x:number,y:number}{
    switch(this.direction){
      case 'Up':
      case 'ArrowUp':
        y -= 10
        break;
      case 'Down':
      case 'ArrowDown':
        y += 10
        break;
      case 'Left':
      case 'ArrowLeft':
        x -= 10
        break;
      case 'Right':
      case 'ArrowRight':
        x += 10
        break;
    }
    return {x,y}
  }
  // 检查蛇是否吃到食物
  checkEat(x:number,y:number):void{
    if(x === this.food.X && y === this.food.Y){
      // 随机刷新食物
      this.food.changeSite()
      // 加分
      this.scorepanel.addScore()
      // 蛇身增加
      this.snake.addBody()
    }
  }
  // 游戏暂停、开始
  puse():void{
    this.isPuse = !this.isPuse 
    if(this.isPuse){
      clearInterval(this.timer)
    } else {
      this.run()
    }
  }
  // 游戏结束
  gameover():void{
    clearInterval(this.timer)
    alert('游戏结束')
    // 刷新页面
    location.reload()
  }

  // 是否掉头了
  isBack(x:number,y:number):boolean{
    if(this.snake.bodies.length === 1) return false
    // 获取第二个蛇身的坐标，如果蛇头将要变化的坐标和第二个蛇身的坐标，表示蛇掉头了
    const left = (this.snake.bodies[1] as HTMLElement).offsetLeft
    const top = (this.snake.bodies[1] as HTMLElement).offsetTop
    if(x === left && y === top) return true
    return false
  }
}

export default Gamecontrol;